﻿using System;
using System.Web.Mvc;
using DingTalk.Api;
using DingTalk.Api.Request;
using DingTalk.Api.Response;
using Newtonsoft.Json;
using WebSite.Class;
using WebSite.Models;
using Xwltz.Framework.Framework;
using Xwltz.Framework.Helper;

namespace WebSite.Controllers
{
    public class BaseController : DbContext
    {
        protected override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            base.OnActionExecuting(filterContext);
            var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
            var actionName = filterContext.ActionDescriptor.ActionName;
            if (Session["AccountModel"] != null)
            {
                if ("Home".Equals(controllerName) && "Index".Equals(actionName)) return;
                if ("Home".Equals(controllerName) && "SignOut".Equals(actionName)) return;
                if ("Api".Equals(controllerName) && "GetList".Equals(actionName)) return;
                if ("Api".Equals(controllerName) && "GetModel".Equals(actionName)) return;
                if ("Api".Equals(controllerName) && "AddOrUpdateModel".Equals(actionName)) return;
                if ("Api".Equals(controllerName) && "ExportExcel".Equals(actionName)) return;
                if ("Api".Equals(controllerName) && "changePwd".Equals(actionName)) return;
                filterContext.Result = RedirectToAction("Index", "Home");
            }
            else
            {
                if ("Home".Equals(controllerName) && "Login".Equals(actionName)) return;
                if ("Home".Equals(controllerName) && "Code".Equals(actionName)) return;
                //重定向至登录页面
                filterContext.Result = RedirectToAction("Login", "Home");
            }
        }

        private string TryGetAccessToken()
        {
            var simpleClient = Db.GetSimpleClient<AccessToken>();
            var access = simpleClient.GetById(1);
            if (access != null)
            {
                if (access.ExpiredTime > DateTime.Now)
                {
                    return access.AccessTokenStr;
                }
                simpleClient.DeleteById(1);
            }

            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
            var req = new OapiGettokenRequest
            {
                Appkey = "dingfzndcu5sg1u4ki9y",
                Appsecret = "UWPF9O7TabVOJ1v1yBaKbvZb9JeKGfOhFtxaOYEZmChyG43UZrGjfQukZVTA_pg1"
            };
            req.SetHttpMethod("GET");
            var rsp = client.Execute(req, "");
            Console.WriteLine(rsp.Body);

            var accessToken = new AccessToken
            {
                Id = 1,
                AccessTokenStr = rsp.AccessToken,
                ExpiredTime = DateTime.Now.AddSeconds(7000)
            };
            simpleClient.Insert(accessToken);
            return accessToken.AccessTokenStr;
        }

        protected string GetByMobile(string mobile)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
            var req = new OapiV2UserGetbymobileRequest();
            req.Mobile = mobile;
            var rsp = client.Execute(req, TryGetAccessToken());

            if (rsp.Errcode.Equals(0) && "ok".Equals(rsp.Errmsg))
            {
                return GetUserInfo(rsp.Result.Userid) ? "" : "error";
            }

            return rsp.ErrMsg;
        }

        protected bool GetUserInfo(string userId)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
            OapiV2UserGetRequest req = new OapiV2UserGetRequest();
            req.Userid = userId;
            OapiV2UserGetResponse rsp = client.Execute(req, TryGetAccessToken());
            return CheckUser(rsp);
        }

        private bool CheckUser(OapiV2UserGetResponse response)
        {
            var user = Db.Queryable<Account>().Single(x => x.UserId.Equals(response.Result.Userid));
            if (user != null) return true;

            var model = new Account
            {
                Name = response.Result.Name,
                Mobile = response.Result.Mobile,
                Avatar = response.Result.Avatar,
                Title = response.Result.Title,
                UserId = response.Result.Userid,
                UnionId = response.Result.Unionid,
                Email = response.Result.Email,
                HiredDate = TimeZone.CurrentTimeZone
                    .ToLocalTime(new System.DateTime(1970, 1, 1))
                    .AddTicks(response.Result.HiredDate * 10000),
                Salt = CommonBase.AutoStr(8)
            };
            model.Password = CryptoService.AESEncrypt(model.Mobile, model.Salt);
            model.AddTime = DateTime.Now;

            var rows = Db.Insertable(model).ExecuteCommand();
            return rows == 1;
        }

        #region 日志操作

        protected void SaveAccountLog(LogTypeEnum type, string dscription = "")
        {
            var model = new AccountLog();
            var session = Session["AccountModel"];
            if (session != null)
            {
                var user = JsonConvert.DeserializeObject<Account>(session.ToString());


                if (user != null)
                {
                    model.UserId = user.Id;
                    model.UserName = user.Name;
                }
            }
            else
            {
                model.UserId = 0;
                model.UserName = string.Empty;
            }

            model.Type = type.ToInt();
            model.Path = Request.RawUrl;
            model.Method = Request.HttpMethod;
            model.Host = ClientHelper.GetIpAddress;
            model.UserAgent = ClientHelper.GetUserAgent();
            model.Area = HostHelper.GetHostInfo(model.Host);
            model.Request = Request.QueryString.ToString();
            model.Response = Response.StatusCode.ToString();
            model.AddTime = DateTime.Now;
            model.Description = dscription;

            new DbContext().GetInstance().Insertable(model).ExecuteCommand();
        }

        #endregion
    }
}